iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
Mobile Development

初窺Flutter系列 第 29

高階主題-表單驗證

  • 分享至 

  • xImage
  •  

表單驗證用於確保用戶輸入的數據有效和合法,可通過Flutter的Form組件和一些驗證器來實現。

以下是一個用於判斷是否有正確填入的Form部分程式範例

Form(
        // 使用 _formKey 作為表單的全局唯一標識
        key: _formKey,
        child: Column(
          children: <Widget>[
            TextFormField(
              decoration: InputDecoration(labelText: '姓名'),// 設置輸入字段的標籤為“姓名”
              validator: (value) {
                if (value!.isEmpty) {
                  return '請輸入姓名';// 如果輸入為空,返回錯誤消息
                }
                return null;// 驗證通過
              },
              onSaved: (value) {
                _name = value!;// 在保存時將輸入的姓名賦值給 _name 變數
              },
            ),
            //創建一個按鈕用於觸發判斷
            ElevatedButton(
              onPressed: () {
                if (_formKey.currentState!.validate()) {
                  _formKey.currentState?.save();
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                    content: Text('已提交,您的姓名是: $_name'),
                  ));
                }
              },
              child: Text('提交'),
            ),
          ],
        ),
      ),

正確填入
https://ithelp.ithome.com.tw/upload/images/20231014/20162684XZwzrrF1eQ.png
錯誤填入
https://ithelp.ithome.com.tw/upload/images/20231014/20162684jasYvElo8K.png

現在我試著為昨天寫的用戶登入加上驗證
在最外圍增加Form,並加入判斷條件:我設定了沒寫姓名跟沒勾選性別會跳錯誤訊息

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LoginScreen(),
    );
  }
}

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  String textInput = '';
  bool isMale = false;
  bool isFemale = false;
  String selectedLanguage = '英文';
  List<String> languageOptions = ['英文', '法文', '西班牙文', '德文', '中文'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('用戶輸入整合'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                TextFormField(
                  decoration: InputDecoration(
                    labelText: '請輸入名字',
                  ),
                  onChanged: (text) {
                    setState(() {
                      textInput = text;
                    });
                  },
                  validator: (value) {
                    if (value!.isEmpty) {
                      return '請輸入名字';
                    }
                    return null;
                  },
                ),
                Row(
                  children: <Widget>[
                    Checkbox(
                      value: isMale,
                      onChanged: (value) {
                        setState(() {
                          isMale = value!;
                          if (isMale) {
                            isFemale = false;
                          }
                        });
                      },
                    ),
                    Text('男性'),
                  ],
                ),
                Row(
                  children: <Widget>[
                    Checkbox(
                      value: isFemale,
                      onChanged: (value) {
                        setState(() {
                          isFemale = value!;
                          if (isFemale) {
                            isMale = false;
                          }
                        });
                      },
                    ),
                    Text('女性'),
                  ],
                ),
                DropdownButton<String>(
                  value: selectedLanguage,
                  onChanged: (String? newValue) {
                    setState(() {
                      selectedLanguage = newValue!;
                    });
                  },
                  items: languageOptions.map((String option) {
                    return DropdownMenuItem<String>(
                      value: option,
                      child: Text(option),
                    );
                  }).toList(),
                ),
                SizedBox(height: 20),
                Text('目前的語言: $selectedLanguage'),
                SizedBox(height: 20),
                ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState!.validate()) {
                      if (isMale || isFemale) {
                        // 表單驗證通過且至少選擇了一個性別
                        showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return AlertDialog(
                              title: Text('已提交'),
                            );
                          },
                        );
                      } else {
                        // 如果沒有選擇性別,顯示錯誤消息
                        showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return AlertDialog(
                              title: Text('錯誤'),
                              content: Text('請選擇男性或女性性別。'),
                            );
                          },
                        );
                      }
                    }
                  },
                  child: Text('提交'),
                ),
                SizedBox(height: 20),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

結果影片
https://imgur.com/a/3LQy68c


上一篇
高階主題-用戶輸入
下一篇
統整回顧三十天
系列文
初窺Flutter30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言